import { boot } from 'quasar/wrappers';
import { ComponentPublicInstance, nextTick, DirectiveBinding } from 'vue';

import { useAppStore, useUserStore } from 'src/stores';

// "async" is optional;
// more info on params: https://v2.quasar.dev/quasar-cli/boot-files
export default boot(async ({ app }) => {
  const errorStore = useAppStore();

  // 记录错误日志
  /* eslint-disable @typescript-eslint/no-explicit-any */
  app.config.errorHandler = (err: any, instance: ComponentPublicInstance | null, info: string) => {
    nextTick(() => {
      const message = err.message ?? '';
      const stack = err.stack ?? '';
      errorStore.addErrorLog({ err: { message, stack }, info, url: window.location.href });
      console.error(info + ',' + window.location.href, err, instance);
    });
  };

  // 注册全局组件
  const excludes = ['../components/ExcelImport.vue']; // 不需要全局定义的组件
  const files = import.meta.glob('../components/*.vue', { eager: true });
  for (const path in files) {
    //const name = path.match(/.*\/(.+).vue$/)[1];
    if (excludes.includes(path)) continue;
    const name = path.substring(14).replace('.vue', '');
    const combo = (files[path] as any).default;
    app.component(name, combo);
  }

  // 注册全局指令
  const userStore = useUserStore();
  const ROLE_SUPER_ADMIN = 'SuperAdmin';
  // need role
  app.directive('has-role', {
    mounted(el: HTMLElement, binding: DirectiveBinding) {
      const { value } = binding;
      if (value) {
        const requiredRoles = Array.isArray(value) ? value : value.split(',');
        const hasRole = userStore.roles.some((role) => {
          return role == ROLE_SUPER_ADMIN || requiredRoles.includes(role);
        });

        if (!hasRole) {
          el.parentNode && el.parentNode.removeChild(el);
        }
      } else {
        throw new Error("need roles! Like v-has-role=\"['admin','test']\"");
      }
    },
  });

  // need permission
  app.directive('has-perm', {
    mounted(el: HTMLElement, binding: DirectiveBinding) {
      const { value } = binding;
      if (value && value instanceof Array && value.length > 0) {
        const requiredPerms = value;
        const hasPerm = userStore.roles.includes(ROLE_SUPER_ADMIN) || userStore.permissions.some((p) => requiredPerms.includes(p));

        if (!hasPerm) {
          el.parentNode && el.parentNode.removeChild(el);
        }
      } else {
        throw new Error('need perms! Like v-has-perm="[\'system:user:add\']"');
      }
    },
  });
});
